import struct

#pack = STX + TIM + LEN + NUM + SEQ + SYS + MSG + PAYLOAD
#-----------------------------------------------------------------#
#         | 字节索引 |         内容            |  值               #
#-----------------------------------------------------------------#
# STX     |    0    | 包起始标志               | 0xFF              #
#-----------------------------------------------------------------#
# TIM     |    1    | 包的时间戳               | 4byte             #
#-----------------------------------------------------------------#
# LEN     |    5    | 有效载荷长度             | 0~1024            #   2Byte
#-----------------------------------------------------------------#
# NUM     |    7    | 组成完整消息的数据包数量  | 2byte             #   最大能传输63Mbyte的数据
#-----------------------------------------------------------------#
# SEQ     |    9    | 包的顺序                | 2byte              #
#-----------------------------------------------------------------#
# SYS     |    11   | 发送者ID                | 0~255              #
#-----------------------------------------------------------------#
# MSG     |    12   | 消息类型                | 0~255              #   最大能传输128种消息，0~127是正常数据包，128~255是冗余包
#-----------------------------------------------------------------#
# PAYLOAD | 13~13+N | 有效载荷                | 0~1024byte         #
#-----------------------------------------------------------------#


def reconstructXor(d1,d2):
    return bytes(p1 ^ p2 for p1, p2 in zip(d1, d2))

def createPacks(tim,chunk_size,sys_id,msg_id,data):
    STX = b'\xff'
    TIM = struct.pack('!I',tim)
    if(len(data)%chunk_size > 0):
        loop_len = int(len(data)/chunk_size) + 1
    else:
        loop_len = int(len(data)/chunk_size)
    NUM = struct.pack('!H',loop_len)
    SYS = struct.pack('B',sys_id)
    MSG = struct.pack('B',msg_id)
    SEQ = {}
    PAYLOAD = {}
    PACKS = {}
    #生成数据包
    for i in range(0,loop_len):
        SEQ[i] = struct.pack('!H',i)
        PAYLOAD[i] = data[chunk_size*i:chunk_size*(i+1)]
        LEN = struct.pack('!H',len(PAYLOAD[i]))
        PACKS[i] = STX + TIM + LEN + NUM + SEQ[i] + SYS + MSG + PAYLOAD[i]
        #print(PACKS[i])
    #生成冗余纠错包
    FEC_LEN = struct.pack('!H',chunk_size)
    FEC_MSG = struct.pack('B',255 - msg_id)
    FEC_PAYLOAD = {}
    j = 0
    for i in range(0,loop_len,2):
        if i == loop_len - 1:
            break
        if(len(PAYLOAD[i+1])<chunk_size):
            FEC_PAYLOAD[j] = reconstructXor(PAYLOAD[i], PAYLOAD[i+1] + b'\x00' * (chunk_size -len(PAYLOAD[i+1])))
        else:
            FEC_PAYLOAD[j] = reconstructXor(PAYLOAD[i], PAYLOAD[i+1])
        j += 1
    FEC_NUM  = struct.pack('!H',j)
    FEC_PACKS = {}
    for i in range(0,j):
        FEC_PACKS[i] = STX + TIM + FEC_LEN + FEC_NUM + SEQ[i] + SYS + FEC_MSG + FEC_PAYLOAD[i]
    return PACKS,FEC_PACKS



def decodePack(data):
    STX = data[0:1]
    TIM = struct.unpack('!I',data[1:5])[0]
    LEN = struct.unpack('!H',data[5:7])[0]
    NUM = struct.unpack('!H',data[7:9])[0]
    SEQ = struct.unpack('!H',data[9:11])[0]
    SYS = data[11]
    MSG = data[12]
    PAYLOAD = data[13:13+LEN]
    if(STX != b'\xff'):
        #数据正确，时间戳，，数据包数量，数据包顺序，发送者ID，消息类型，有效数据
        return False,None,None,None,None,None,None,None
    return True,TIM,LEN,NUM,SEQ,SYS,MSG,PAYLOAD

def decodeFEC(PACKS,FEC_PACKS,NUM,size):
    j = 0
    try:
        for i in range(0,NUM,2):
            if(i == (NUM -1)):
                break
            if(PACKS[i] == None):
                if FEC_PACKS[j] == None or PACKS[i+1] == None:
                    return None
                else:
                    #print("可以还原")
                    if(len(PACKS[i+1]) < size):
                        PACKS[i] = reconstructXor(PACKS[i+1] + b'\x00' * (size -len(PACKS[i+1])),FEC_PACKS[j])
                    else:
                        PACKS[i] = reconstructXor(PACKS[i+1],FEC_PACKS[j])
            elif(PACKS[i+1] == None):
                if FEC_PACKS[j] == None or PACKS[i] == None:
                    return None
                else:
                    PACKS[i] = reconstructXor(PACKS[i],FEC_PACKS[j])
    except:
        return None
    #print("还原完毕")
    data = b''
    for i in range(0,NUM-1):
        data += PACKS[i]
    return data

